$fn = 80; HALFCUT = 0; // cut it at all CUT = 1; // side: left or right 0 / 1 // ----------- testing --------------------- CUT_DIA = 0; // diametrical cut (for testing) FLATCUT = 0; // HELPERS = false; BODY = 0; // ---------- main settings ---------------- width = 50; height = 100; length = 83; angle = 15; lift = 20; neo_w = 62; // 62 neo_h = 120; // 120 neo_l = 25; // 25 ERR = 0.1; // to remove thin junction walls EXT = 2; // to extend inner caves & notches // ---------- rounded rectangle ------------ module roundedBody( w, h, l, r ){ // r = 2; w = w-r*2; h = h-r*2; // translate([0, 0, 0]) hull() { cylinder( l, r, r ); translate([0, w, 0]) cylinder( l, r, r ); translate([h, 0, 0]) cylinder( l, r, r ); translate([h, w, 0]) cylinder( l, r, r ); } } // color("blue") roundedBody( 20, 10, 10, 5 ); // ---------- pancake (4 light) ----------- module pancake(r1,h,r2){ translate([0, 0, r2]) minkowski(){ cylinder(h-r2*2,r1-r2,r1-r2); sphere(r2); } } // ---------- holder (vertical part) ------- M = [[ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ tan(angle), 0, 1, 0 ], [ 0, 0, 0, 1 ]] ; module verticalPart(){ module glassNotch(){ intersection(){ translate([85,0,28]) color("red") pancake(22,22,9.9); difference(){ roundedBody( width-2, height-2, length, width/2 ); roundedBody( width-4, height-4, length, width/2 ); } } } difference(){ multmatrix(M) roundedBody( width, height, length, width/2 ); translate([-40, (width+1)/2, -10 - lift]) rotate([90,0,0]) color("red") roundedBody( 60, 80, width+1, width/4 ); // light front translate([85,0,28]) color("red") pancake(20,20,9.9); translate([0,0,-1]) glassNotch(); translate([51, 0, 31]) color("red") { translate([-2, 0, 4]) cube([27, 17 + 2 + EXT, 8], center=true); translate([4, 0, 5]) cube([15 + EXT, 17 + 2 + EXT, 10], center=true); translate([10, -EXT/2, 7]) rotate([0,90,0]) color("red") translate([0, -4, 0]) roundedBody( 12 + EXT, 6, 10, 2 ); // button hole translate([1 - 2, 0, -20]) cylinder(20, 1.2 + EXT/2, 1.2 + EXT/2); translate([1 - 2, 0, -5]) cylinder(6, 5+1, 5+1); } translate([54, 0, -3]) color("red") sphere(20); // extra hidden hole translate([35, -44, 31]) translate([0,30,0]) rotate([90,0,0]) cylinder( 18,3,3, center=true); // charger translate([35, 0, 25 + EXT/2]) color("red") cube([5 + EXT, 34 + EXT,23 + 1 + EXT], center=true); // charger translate([35 - EXT/2,-12 - EXT/2,6]) roundedBody( 12 + EXT/2, 7 + EXT/2, 10 + EXT, 3 ); // usb hole // bolts boltDia = 3.5; translate([15,0,79]) color("red") { translate([0,62/2,0]) rotate([90,0,0]) cylinder(62,boltDia/2,boltDia/2); // bolt 62mm translate([0,-width/2+3,0]) rotate([90,0,0]) cylinder(6,6,10); translate([0,width/2+3,0]) rotate([90,0,0]) cylinder(6,10,6); } translate([15,0,31]) color("red") { translate([0,62/2,0]) rotate([90,0,0]) cylinder(62,boltDia/2,boltDia/2); // bolt 62mm translate([0,-width/2+3,0]) rotate([90,0,0]) cylinder(6,6,10); translate([0,width/2+3,0]) rotate([90,0,0]) cylinder(6,10,6); } } } // ---------- neo (horisontal part) -------- module neoHolder( w, h, l, thin ){ MRad = 10 - EXT; BMRad = 19; roundPad = 0.7; difference(){ translate([0, 0, BMRad/2]) minkowski() { roundedBody( w+thin*2 - BMRad, h+thin*2 - BMRad, l - BMRad, (w+thin*2 - BMRad)/2 ); sphere(BMRad/2); } translate([-EXT/2, -EXT/2, thin + MRad/2 + ERR -1]) color("red") minkowski() { roundedBody( w-MRad + EXT, h-MRad + EXT, l-MRad, (w-MRad)/2 ); sphere(MRad/2); } rotate([90, 0, 0]) translate([16 - EXT/2, 18-2, -50]) roundedBody(20,12 + EXT,100,3); // micro usb hole rotate([90, 0, 0]) translate([8, 20 - 1, 0]) cylinder(100,3/2,3/2); // button hole rotate([90, 0, 0]) translate([70 + 1,20,-40]) cylinder(20,3/2,3/2); // left button hole translate([-50,0.5,-10]) rotate([50, 0, 90]) roundedBody(25,5,50,3); // center safty hole translate([17,-27,13]) rotate([90, 0, 90]) roundedBody(18,20,4,6); // usb wire channel // soft pad translate([-roundPad - EXT/2, -roundPad - EXT/2, thin + 5]) color( "green" ) roundedBody( w+roundPad*2 + EXT, h+roundPad*2 + EXT, l * 0.28, w/2 ); } } // ---------- soft connect ----------------- module softConnect( width, height, raduis ){ // inner size w = width + raduis*4; h = height + raduis*4; module halfTorus(){ difference(){ rotate_extrude(convexity = 0) translate([w/2-raduis, 0, 0]) circle(raduis); color("green") translate([-w/2, 0, -raduis]) cube([w, w/2, raduis*2]); } } module roundedSubObject(){ halfTorus(); translate([0, h-w, 0]) rotate([0, 0, 180]) halfTorus(); translate([w/2-raduis, -ERR/2, 0]) rotate([-90,0,0]) cylinder(h-w+ERR,raduis,raduis); translate([-(w/2-raduis), -ERR/2, 0]) rotate([-90,0,0]) cylinder(h-w+ERR,raduis,raduis); } difference(){ rotate([0, 0, 90]) roundedBody( w-raduis*2, h-raduis*2, raduis, (w-raduis*2)/2 ); roundedSubObject(); } } // ---------- handle bar ----------------- handleR = 27/2; // diameter of vertical part of the handleR2 = 32/2; // 35/2 // diameter of horisontal part handleAng = 25; // 20 module handle(){ horScale = 1.1; // vertical part translate([0,0,-10]) scale([1, horScale, 1]) cylinder( 86, handleR, handleR); // diagonal part translate([95, 0, 83]) rotate([0, -90-handleAng, 0]) scale([1, horScale, 1]) linear_extrude(height=100, scale=[1.3,0.77], slices=20, twist=0) circle(handleR2); // wire aound the handle bar color("red") intersection(){ translate([88, 0, 80]) rotate([0, -90-handleAng, 0]) linear_extrude(height=100, scale=[1.4,0.9], slices=20, twist=0) scale([1, horScale, 1]) circle(handleR2); rotate([0, -90-handleAng+5, 0]) translate([0,0,-46]) cylinder(6,100,100); } } // ---------- main part ------------------ module holder(){ verticalPart(); translate([0, 0, length]) multmatrix(M) rotate([0,0,-90]) softConnect( width, height, 8 ); translate([0, 0, length + 8 - ERR]) rotate([0, -angle, 0]) translate([-1,0,0]) neoHolder(neo_w, neo_h, neo_l, 10 ); } module main() { difference(){ translate([0,0, 20 + lift ]) holder(); // main part translate([0,0,50]) handle(); // handle bar // under device holes translate([0,0,120+lift]) rotate([0, 90-angle, 0]) color("red") { translate([-2, -18+3 - EXT/2, 57]) rotate([0,90,0]) roundedBody(36 + EXT, 52 + EXT,14,3); // battery hole translate([-2, -18+10 - EXT/2, 10]) rotate([0,90,0]) roundedBody(36 + EXT, 37,8,10); // plug usb place translate([-6, -20, 12.5]) cube([20,20,6]); // plug usb channel } // wires path translate([34, 0, 77]) rotate([0, -handleAng + 5, 0]) color("red") translate([2,0,30]) cube([6,4,65], center=true); // vertical cutter if ( HALFCUT ) { if ( CUT ) translate([-neo_h/2,0 , 0]) cube([neo_h*1.5, neo_w*2, length*2.5]); else mirror([0,1,0]) translate([-neo_h/2,0 , 0]) cube([neo_h*1.5, neo_w*2, length*2.5]); // vertical cutter } // perpendicular testing cutter if ( CUT_DIA ) { mirror([1,0,0]) translate([-neo_h/3,0 , 0]) cube([neo_h*1.5, neo_w*2, length*2.5]); } } } if ( FLATCUT ) { // projection(cut=true) translate([0,0,0]) rotate([90,0,0]) // to make flat cut projection for SVG testing export projection(cut=true) translate([0,0,-105]) // to make flat cut projection for SVG testing export main(); } else { main(); } // ---------- control mesurement ---------- // neo dummy module module neoDummy(){ rad = 5; outerRad = 26; translate([rad,rad,rad]) color("purple") minkowski() { translate([outerRad,outerRad,0]) roundedBody(62-rad*2, 120-rad*2, 19-rad*2, outerRad ); sphere(rad); } translate([39,0,0]) rotate([90,0,0]) translate([0,19/2,-100/2]) color("green") cylinder(100,1,1); // 39 button translate([50,0,0]) rotate([90,0,0]) translate([0,19/2,-100/2-62/2]) color("green") cylinder(100,1,1); // 50 usb + jack translate([120-19,0,0]) rotate([90,0,0]) translate([0,19/2,-100/2-62/2]) color("green") cylinder(100,1,1); // 19 from top, button left } if ( BODY ) translate([0, 0, 122 + lift]) rotate([0,-angle,0]) translate([-35,-31,0]) neoDummy() // neo dummy if ( HELPERS ) translate([10, -18+3, length + 36 + lift]) rotate([0, 90-angle, 0]) color("purple") roundedBody(35,10,50,3); // battery if ( HELPERS ) translate([0, 0, 20]) { translate([20, 0, 77]) rotate([0, -110, 0]) color("red") cube([36,1,1], center=true); translate([0, 0, 100]) rotate([0, 90, 0]) color("red") cube([10,1,1], center=true); translate([5, 0, 70]) rotate([0, 90, 0]) color("red") cube([70,1,1], center=true); translate([-5, 0, 61]) rotate([0, 90, 0]) color("red") cube([88,1,1], center=true); translate([0, 0, 16]) color("red") cylinder(19,39/2,35/2); translate([0, 0, 6]) color("red") cylinder(10,50/2,50/2); translate([45, 0, 100]) rotate([0, -18, 0]) color("red") cube([67,1,1], center=true); translate([0,62/2,0]) rotate([90,0,0]) color("red") cylinder(62,3/2,3/2); // bolt 62mm }